import { BattleCard, Skill, SkillInfo, CardAction, TargetAction } from '../types';

export const atkAction = async (
  ownCards: BattleCard[],
  foeCards: BattleCard[],
  card: BattleCard,
  skl: SkillInfo,
  target: BattleCard[],
) => {
  const action: CardAction = {
    from: card.from,
    to: target.map(v => v.from)[0],
    id: card.base.id,
    avatar: card.base.heroAvatar,
    skill: skl.skill.id,
    skillType: skl.type,
    angry: 0,
    target: [],
  };

  // 出手后怒气处理 -先清空，后补充
  if (skl.type === 2) {
    card.battle.ANGRY = 0;
  }

  // 攻击开始
  for (let i = 0; i < target.length; i++) {
    const v = target[i];
    // 是否命中
    const hit = isHit(card, v);
    console.log(`命中：${hit}`);
    // 是否暴击
    const crit = isCrit(card, v);
    console.log(`暴击：${crit}`);
    // 计算伤害数值
    const dmg = calcDmg(hit, crit, card, v, skl.skill);
    console.log(`伤害：${dmg}`);
    // 伤害处理
    v.battle.HP -= dmg;
    // 判断是否死亡
    console.log(`剩余血量：${v.battle.HP}`);
    // 怒气增加 被攻击增加5点怒气
    v.battle.ANGRY = v.battle.ANGRY + 5 > 100 ? 100 : v.battle.ANGRY + 5;

    const targetAction: TargetAction = {
      from: v.from,
      id: v.base.id,
      action: skl.skill.action,
      buff: [],
      hit: hit ? 1 : 0,
      crit: crit ? 1 : 0,
      dmg: dmg,
      die: v.battle.HP === 0 ? 1 : 0,
      recover: 0,
      hp: v.battle.HP,
      angry: v.battle.ANGRY,
    };

    action.target.push(targetAction);

    if (v.battle.HP === 0) {
      const type = await targetDie(ownCards, foeCards, v);
      if (type.includes('战斗')) {
        break;
      }
    }

    // 是否有附加效果
    const { additional } = skl.skill;
    if (additional > 0) {
      // 附加效果
      for (let j = 1; j <= additional; j++) {
        const key = `logic${j}`;
        const logicKey = skl.skill[`${key}` as keyof Skill] as number;
        const logicType = skl.skill[`${key}_type` as keyof Skill] as number;
        const logicValue = skl.skill[`${key}_parameter` as keyof Skill] as number;
        const logicRound = skl.skill[`${key}_round` as keyof Skill] as number;

        const newBuff = {
          BUFF: logicKey,
          EFF: logicType,
          TYPE: logicValue > 100 ? 1 : 0,
          VAL: logicValue,
          RND: logicRound,
        };
        v.buff.push(newBuff);

        targetAction.buff.push(newBuff);
      }
    }
  }

  card.battle.ANGRY = card.battle.ANGRY + 10 > 100 ? 100 : card.battle.ANGRY + 10;
  action.angry = card.battle.ANGRY;

  return action;
};

/**
 * 是否命中
 * @param {BattleCard} card 卡牌
 * @param {BattleCard} target 目标
 */
const isHit = (card: BattleCard, target: BattleCard) => {
  const { HIT } = card.battle;
  const { PRY } = target.battle;
  return (HIT - PRY) / 200 + 0.5 > Math.random();
};

/**
 * 是否暴击
 * @param {BattleCard} card 卡牌
 * @param {BattleCard} target 目标
 */
const isCrit = (card: BattleCard, target: BattleCard) => {
  const { CRIT } = card.battle;
  const { CRIRES } = target.battle;
  return (CRIT - CRIRES) / 200 + 0.5 > Math.random();
};

/**
 * 计算伤害 【使用减法公式】
 * @param {BattleCard} card 卡牌
 * @param {BattleCard} target 目标
 * @param {Skill} skl 技能
 */
const calcDmg = (hit: Boolean, crit: Boolean, card: BattleCard, target: BattleCard, skl: Skill) => {
  if (!hit) {
    return 0;
  }

  const { ATK, DMGADD } = card.battle;
  const { DEF, DMGRED } = target.battle;
  const { ratio } = skl;

  // 伤害 = 攻击 * 技能系数 - 防御 / 2
  const dmgNum = ATK * (ratio / 100) - DEF / 2;
  console.log(`伤害数值：${dmgNum}`);
  // 加深和减免的计算应该是 （加深-减免） / 1000 + 1
  const otherRatio = (DMGADD - DMGRED) / 1000 + 1;

  const dmg = Math.round(dmgNum * otherRatio) <= 0 ? 1 : Math.round(dmgNum * otherRatio);

  let realyDmg = crit ? dmg * 2 : dmg;
  if (realyDmg >= target.battle.HP) {
    realyDmg = target.battle.HP;
  }

  return realyDmg;

  //old
  // const atkNum = ATK * (DMGADD / 1000 + 1) * (ratio / 100);
  // console.log(`攻击数值：${atkNum}`);
  // const defNum = ((ATK * DEF) / (1200 + DEF)) * (DMGRED / 1000 + 1);
  // console.log(`防御数值：${defNum}`);
  // console.log(`伤害：${Math.round(atkNum - defNum)}`);
  // return Math.round(atkNum - defNum);
};

/**
 * 目标卡牌死亡
 * @param {BattleCard} card 卡牌
 */

const targetDie = (
  ownCards: BattleCard[],
  foeCards: BattleCard[],
  card: BattleCard,
): Promise<string> => {
  return new Promise((resolve, reject) => {
    const { from, base } = card;
    const { id } = base;

    // 从阵容中删除
    if (from === 'OWN') {
      console.log('\x1b[31m%s\x1b[0m', `我方卡牌：${card.base.id}阵亡`);
      const index = ownCards.findIndex(v => v.base.id === id);
      ownCards.splice(index, 1);
    } else {
      console.log('\x1b[31m%s\x1b[0m', `敌方卡牌：${card.base.id}阵亡`);
      const index = foeCards.findIndex(v => v.base.id === id);
      foeCards.splice(index, 1);
    }

    // 判断是否还有卡牌存活
    if (ownCards.length === 0) {
      resolve('战斗失败');
      // throw new Error('战斗失败');
    }

    if (foeCards.length === 0) {
      resolve('战斗胜利');
      // throw new Error('战斗胜利');
    }

    resolve('next');
  });
};
